<?php
// 应用公共文件

use think\Response;
use think\response\Json;
use think\facade\Request;
use think\facade\Db;
use think\facade\Cache;



/**
 * User: 意象信息科技 lr
 * Desc: 表单多维数据转换
 * 例：
 * 转换前：{"x":0,"a":[1,2,3],"b":[11,22,33],"c":[111,222,3333,444],"d":[1111,2222,3333]}
 * 转换为：[{"a":1,"b":11,"c":111,"d":1111},{"a":2,"b":22,"c":222,"d":2222},{"a":3,"b":33,"c":3333,"d":3333}]
 * @param array $arr 表单二维数组
 * @param bool $fill fill为false，返回数据长度取最短，反之取最长，空值自动补充
 * @return array
 */
if(!function_exists('formToLinear')){
    function formToLinear(array $arr,bool $fill = false):array
    {
        $keys = [];
        $count = $fill ? 0 : PHP_INT_MAX;
        foreach ($arr as $k => $v) {
            if (is_array($v)) {
                $keys[] = $k;
                $count = $fill ? max($count, count($v)) : min($count, count($v));
            }
        }
        if (empty($keys)) {
            return [];
        }
        $data = [];
        for ($i = 0; $i < $count; $i++) {
            foreach ($keys as $v) {
                $data[$i][$v] = $arr[$v][$i] ?? null;
            }
        }
        return $data;
    }
}


/**
 * 非常给力的encrypt_code加密函数,Discuz!经典代码
 *
 * @param string $string 字符串，明文或密文；
 * @param string $operation DECODE表示解密，其它表示加密；
 * @param string $key 密匙；
 * @param int $expiry 密文有效期。
 *
 * @return string
 *
 */
if(!function_exists('encryptCode')){
    function encryptCode(string $string,string $operation = 'DECODE',string $key = '',int $expiry = 0):string
    {
        // 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙
        $ckey_length = 4;

        // 密匙
        $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);

        // 密匙a会参与加解密
        $keya = md5(substr($key, 0, 16));
        // 密匙b会用来做数据完整性验证
        $keyb = md5(substr($key, 16, 16));
        // 密匙c用于变化生成的密文
        $keyc =  $operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length);
        // 参与运算的密匙
        $cryptkey = $keya . md5($keya . $keyc);
        $key_length = strlen($cryptkey);
        // 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，
        //解密时会通过这个密匙验证数据完整性
        // 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确
        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
        $string_length = strlen($string);
        $result = '';
        $box = range(0, 255);
        $rndkey = array();
        // 产生密匙簿
        for ($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }
        // 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上对并不会增加密文的强度
        for ($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        // 核心加解密部分
        for ($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            // 从密匙簿得出密匙进行异或，再转成字符
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }
        if ($operation == 'DECODE') {
            // 验证数据有效性，请看未加密明文的格式
            if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            // 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因
            // 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码
            return $keyc . str_replace('=', '', base64_encode($result));
        }

    }
}


/**
 * 取汉字的第一个字的首字母
 * @param string $str 汉字字符串
 *
 * @return string
 */
if(!function_exists('getFirstChar')){
    function getFirstChar(string $str):string
    {
        if (empty($str)) {
            return '';
        }

        $fir = $fchar = ord($str[0]);
        if ($fchar >= ord('A') && $fchar <= ord('z')) {
            return strtoupper($str[0]);
        }

        $s1 = @iconv('UTF-8', 'gb2312//IGNORE', $str);
        $s2 = @iconv('gb2312', 'UTF-8', $s1);
        $s = $s2 == $str ? $s1 : $str;
        if (!isset($s[0]) || !isset($s[1])) {
            return '';
        }

        $asc = ord($s[0]) * 256 + ord($s[1]) - 65536;

        if (is_numeric($str)) {
            return $str;
        }

        if (($asc >= -20319 && $asc <= -20284) || $fir == 'A') {
            return 'A';
        }
        if (($asc >= -20283 && $asc <= -19776) || $fir == 'B') {
            return 'B';
        }
        if (($asc >= -19775 && $asc <= -19219) || $fir == 'C') {
            return 'C';
        }
        if (($asc >= -19218 && $asc <= -18711) || $fir == 'D') {
            return 'D';
        }
        if (($asc >= -18710 && $asc <= -18527) || $fir == 'E') {
            return 'E';
        }
        if (($asc >= -18526 && $asc <= -18240) || $fir == 'F') {
            return 'F';
        }
        if (($asc >= -18239 && $asc <= -17923) || $fir == 'G') {
            return 'G';
        }
        if (($asc >= -17922 && $asc <= -17418) || $fir == 'H') {
            return 'H';
        }
        if (($asc >= -17417 && $asc <= -16475) || $fir == 'J') {
            return 'J';
        }
        if (($asc >= -16474 && $asc <= -16213) || $fir == 'K') {
            return 'K';
        }
        if (($asc >= -16212 && $asc <= -15641) || $fir == 'L') {
            return 'L';
        }
        if (($asc >= -15640 && $asc <= -15166) || $fir == 'M') {
            return 'M';
        }
        if (($asc >= -15165 && $asc <= -14923) || $fir == 'N') {
            return 'N';
        }
        if (($asc >= -14922 && $asc <= -14915) || $fir == 'O') {
            return 'O';
        }
        if (($asc >= -14914 && $asc <= -14631) || $fir == 'P') {
            return 'P';
        }
        if (($asc >= -14630 && $asc <= -14150) || $fir == 'Q') {
            return 'Q';
        }
        if (($asc >= -14149 && $asc <= -14091) || $fir == 'R') {
            return 'R';
        }
        if (($asc >= -14090 && $asc <= -13319) || $fir == 'S') {
            return 'S';
        }
        if (($asc >= -13318 && $asc <= -12839) || $fir == 'T') {
            return 'T';
        }
        if (($asc >= -12838 && $asc <= -12557) || $fir == 'W') {
            return 'W';
        }
        if (($asc >= -12556 && $asc <= -11848) || $fir == 'X') {
            return 'X';
        }
        if (($asc >= -11847 && $asc <= -11056) || $fir == 'Y') {
            return 'Y';
        }
        if (($asc >= -11055 && $asc <= -10247) || $fir == 'Z') {
            return 'Z';
        }

        return '';
    }
}


 /**
 * 生成密码（新）
 * @param string $psd    明文密码
 *
 * @return string
 */
if(!function_exists('ph')){
    function ph(string $psd):string
    {
        return password_hash($psd, PASSWORD_DEFAULT);
    }
}

/**
 * 校验密码
 * @param string $psd          明文密码
 * @param string $hash         哈希值(密文密码)
 *
 * @return bool
 * */
if(!function_exists('pv')){
    function pv(string$psd,string $hash):bool
    {
        return password_verify($psd, $hash);
    }
}


/**
 * 整型数字加密
 * @param $data string|int  加密整数或加密字符串
 * @param bool $type    类型：true 加密，false解密
 * @return string|int
 * */
if(!function_exists('intCode')){
    function intCode($data,bool $type = false)
    {
        $result = '';
        $len = strlen($data);
        if ($type) {
            if (!is_numeric($data)) {
                return '';
            }
            $temCode = mt_rand(0, 43);
            $temCodeA = $temCode + 48;
            if ($temCodeA >= 58 && $temCodeA < 65) {
                $temCodeA = $temCodeA + 52;
            }
            if ($temCodeA >= 91 && $temCodeA < 97) {
                $temCodeA = $temCodeA + 26;
            }
            $result .= chr($temCodeA);
            //加密
            for ($i = 0; $i < $len; $i++) {
                $d = substr($data, $i, 1);
                $l = $i ? substr($data, $i - 1, 1) : 9;
                $n = $l + $d + $temCode + 48;
                if ($n >= 58 && $n < 65) {
                    $n = $n + 52;
                }
                if ($n >= 91 && $n < 97) {
                    $n = $n + 26;
                }
                $result .= chr($n);
            }
        } else {
            //解密
            if ($len < 2) {
                return '';
            }
            $number = [];
            $temCodeNum = ord(substr($data, 0, 1));
            $tcBc = $temCodeNum >= 110 ? ($temCodeNum < 117 ? 52 : 26) : 0;
            $temCode = $temCodeNum - 48 - $tcBc;
            for ($i = 1; $i < $len; $i++) {
                $d = substr($data, $i, 1);
                $l = $i > 1 ? $number[$i - 2] : 9;
                $n = ord($d);
                $bc = $n >= 110 ? ($n < 117 ? 52 : 26) : 0;
                $number[] = $n - $l - $temCode - 48 - $bc;
            }
            $result = intval(implode('', $number));
        }
        return $result;
    }

}

/**
 * 去除emoji表情字符串
 *
 * @param string $str 原字符串
 *
 * @return string
 * */
if(!function_exists('filterEmoji')){
    function filterEmoji(string $str):string
    {
        return preg_replace_callback('/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);
    }
}


/**
 * 生成随机码
 * @param int $length 随机码长度
 * @param string $prefix uniqid混淆字符串
 * @return  string
 */
if(!function_exists('createRandomCode')){
    function createRandomCode(int $length = 12,string $prefix = 'hy'):string
    {
        $uniqid = uniqid($prefix, true);
        $param_string = $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['SERVER_SOFTWARE'] . time() . rand() . $uniqid;
        $sha1 = strtoupper(sha1($param_string));
        $code = '';
        $str = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        for ($f = 0; $f < $length; $f++) {
            $g = ord($sha1[$f]);
            $code .= $str[($g ^ ord($sha1[$f + 8])) - $g & 0x1F];
        };
        return $code;
    }
}


/**
 * 高精度数学计算函数
 * @param float|int|string $num1 数字1
 * @param float|int|string $num2 数字2
 * @param int $type 计算类型：1:加法 2:减法 3:乘法 4:除法 5:高精度比较
 * @param int $scale 保留小数位
 * @param bool $round 是否四舍五入
 *
 * @return  float|int
 */
if(!function_exists('bc')){
    function bc($num1, $num2,int $type = 1,int $scale = 2,bool $round = false)
    {
        $scale_new = $round ? $scale + 1 : $scale;
        $num1 = is_numeric($num1) ? $num1 : 0;
        $num2 = is_numeric($num2) ? $num2 : 0;
        switch ($type) {
            case 1:
                $result = bcadd($num1, $num2, $scale_new);
                break;
            case 2:
                $result = bcsub($num1, $num2, $scale_new);
                break;
            case 3:
                $result = $num1 && $num2 ? bcmul($num1, $num2, $scale_new) : 0;
                break;
            case 4:
                $result = $num1 && $num2 ? bcdiv($num1, $num2, $scale_new) : 0;
                break;
            default:
                return 0;
        }
        return $round ? round($result, $scale) : $result;
    }
}


/**
 * 抽奖
 * @param array $proArr 抽奖数组，返回键名
 * @return  string
 * */
if(!function_exists('lotto')){
    function lotto(array $proArr):string
    {
        //概率数组的总概率精度
        $proSum = array_sum($proArr);
        $k = 0;
        //概率数组循环
        foreach ($proArr as $key => $proCur) {
            $randNum = mt_rand(1, $proSum);
            if ($randNum <= $proCur) {
                $k = $key;
                break;
            } else {
                $proSum -= $proCur;
            }
        }
        return $k;
    }
}


/**
 * 生成订单号
 * @param string $str 前缀
 * @return string
 * */
if(!function_exists('createOrderNo')){
    function createOrderNo(string $str = ''):string
    {
        $str = strlen($str) > 4 ? substr($str, 0, 4) : $str;
        return $str . date('YmdHis') . mt_rand(100000, 999999);
    }
}




/**
 * 敏感字符串加密处理
 * @param string $raw_str 原始字符串
 * @param int $before 前面保留的显示位数
 * @param int $after 后面保留的显示位数
 * @param string $replace_char 中间替换的字符，默认为*
 *
 * @return string
 */
if(!function_exists('replaceSensitiveStr')){
    function replaceSensitiveStr(string $raw_str,int $before = 1,int $after = 1,string $replace_char = '*'):string
    {
        $str_before = mb_substr($raw_str, 0, $before);
        $str_after = mb_substr($raw_str, 0 - $after);
        $len = mb_strlen($raw_str) - mb_strlen($str_before) - mb_strlen($str_after);
        $multiplier = $len > 0 ? $len : 1;
        $middle_str = str_repeat($replace_char, $multiplier);
        return ($str_before . $middle_str . $str_after);
    }
}



/**
 * 获取富文本中的纯文本内容
 *
 * @param string $sting 富文本内容
 * @param bool $trim    是否去除空格
 *
 * @return string
 * */
if(!function_exists('getContent')){
    function getContent(string $string,bool $trim = true):string
    {
        if ($string) {
            $html_string = htmlspecialchars_decode($string);

            if ($trim) {
                $html_string = str_replace(' ', '', $html_string);
            }

            return strip_tags($html_string);
        } else {
            return $string;
        }
    }
}



/**
 * curl远程请求
 *
 * @param string $url 请求地址
 * @param array|string $data    请求body
 * @param array $header     请求头
 * @param array $proxy      代理 ['host'=>"代理host",'port'=>"端口号",'user'=>"http代理认证帐号，username:password的格式"]
 * @param bool $ssl         是否验证ssl证书
 * @param int $timeOut      超时时间（秒）
 *
 * @return string
 * */
if(!function_exists('httpCurl')){
    function httpCurl(string $url, $data = '',array $header = [],array $proxy = [],bool $ssl = false,int $timeOut = 30,&$info=null):string
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);

        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        if (count($header)) {
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        }

        if (is_array($proxy) && isset($proxy['host'])) {
            curl_setopt($curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); //代理认证模式
            curl_setopt($curl, CURLOPT_PROXY, $proxy['host']);
            curl_setopt($curl, CURLOPT_PROXYPORT, $proxy['port']);
            if (isset($proxy['user']) && $proxy['user']) {
                curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxy['user']); //http代理认证帐号，username:password的格式qq233631527:bId8UoQhelA512mK
            }

            curl_setopt($curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); //使用http代理模式
        }

        if (!$ssl) {
            curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        } else {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
            //curl_setopt($curl, CURLOPT_CAINFO, env('root_path') . 'cert/cacert.pem');
        }


        curl_setopt($curl, CURLOPT_ENCODING, '');//设置解压类型
        curl_setopt($curl, CURLOPT_TIMEOUT, $timeOut); // 设置超时限制防止死循环

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);

        $info = curl_getinfo($curl);

        //返回结果
        curl_close($curl);
        return $output;
    }
}



/**
 * 下划线转驼峰（数组）
 * @param array $data 数据数组
 *
 * @return array
 * */
if(!function_exists('toCamelCase')){
    function toCamelCase(array $data):array
    {
        $result = [];
        if (count($data)) {
            foreach ($data as $k => $v) {
                if (is_array($v)) {
                    $value = toCamelCase($v);
                } else {
                    $value = $v;
                }
                $key = strToCamelCase($k);
                $result[$key] = $value;
            }
        }
        return $result;
    }
}

/**
 * 下划线转驼峰（字符串）
 * @param string $str 数据数组
 *
 * @return string
 * */
if(!function_exists('strToCamelCase')){
    function strToCamelCase(string $str):string
    {
        $newStr = '';
        if(strlen($str)){
            $keys = explode('_', $str);
            $newStr = array_shift($keys);
            if (count($keys)) {
                foreach ($keys as $val) {
                    $newStr .= ucfirst($val);
                }
            }
        }
        return $newStr;
    }
}

/**
 * 驼峰转下划线（数组）
 *
 * @param array $data 数据数组
 * @return array
 * */
if(!function_exists('toUnderline')){
    function toUnderline(array $data):array{
        $result = [];
        if (count($data)) {
            foreach ($data as $keys => $v) {
                if (is_array($v)) {
                    $value = toUnderline($v);
                } else {
                    $value = $v;
                }
                $key = strToUnderline($keys);//新key
                $result[$key] = $value;
            }
        }
        return $result;
    }
}

/**
 * 驼峰转下划线（字符串）
 *
 * @param string $str 需要转换的字符串
 * @return string
 * */
if(!function_exists('strToUnderline')){
    function strToUnderline(string $str):string{
        $newStr = '';
        $str = trim($str);
        if(strlen($str)){
            $keys = lcfirst($str);//首字母小写
            $keys = str_split($keys);//拆分数组遍历
            foreach ($keys as $k) {
                $temp_k = $k;
                if(preg_match('/[A-Z]+/',$k)){
                    $temp_k = '_'.strtolower($k);
                }
                $newStr .= $temp_k;
            }
        }
        return $newStr;
    }
}

/**
 * 响应json数据并将数据中的键名转成驼峰
 *
 * @param array $data 响应数据
 * @param int $code 响应code
 * @param array $header 响应头
 * @param array $options 响应参数
 *
 * @return Json
 * */
if(!function_exists('jJson')){
    function jJson(array $data = [],int $code = 200,array $header = [],array $options = []): Json
    {
        $data = json_decode(json_encode($data), true);
        $data = toCamelCase($data);
        return Response::create($data, 'json', $code)->header($header)->options($options);
    }
}

/**
 * 总后台响应并保存日志
 *
 * @param \think\Request $request
 * @param array $data
 * @param string $action
 * @param int $code
 * @param array $header
 * @param array $options
 * @return Json
 *
 * */
if(!function_exists('returnAdmin')){
    function returnAdmin(\think\Request $request,array $data = [],string $action = '',array $user = [],int $code = 200,array $header = [],array $options = []):Json
    {
        $param = $request->param();
        //去除富文本字段
        unset($param['detail'], $param['content'],$param['auth_user_name'],$param['auth_user_status']);
        if(isset($param['password'])){
            $param['password'] = $param['password'] ? '******' : '';
        }
        if(isset($param['repassword'])){
            $param['repassword'] = $param['repassword'] ? '******' : '';
        }
        if(isset($param['psd'])){
            $param['psd'] = $param['psd'] ? '******' : '';
        }
        //处理msg,防止超长
        $msg = $data['msg'] ?? '';
        if(strlen($msg) > 255){
            $msg = mb_substr($msg,0,82).'...';
        }
        //添加系统日志
        $log = [
            'uid' => $user['id'] ?? 0,
            'admin' => $user['nickname'] ?? '',
            'ip' => $request->ip(),
            'query' => !empty($param)?json_encode($param):'',
            'url' => $request->controller().'/'.$request->action(),
            'action' => $action,
            'msg' => $msg,
            'method' => $request->method(),
            'create_time' => getDateTime('U'),
        ];
        Db::name('log')->insert($log);

        return jJson($data,  $code, $header, $options);
    }
}

/**
 * 去除域名
 * @param string $str url地址
 *
 * @return string
 * */
if(!function_exists('removeDomain')){
    function removeDomain(string $str):string
    {
        if(!$str) return $str;
        $host = Request::host();
        $str_arr = parse_url($str);
        $pathHost = $str_arr['host'] ?? '';
        if($pathHost && $pathHost !== $host){
            return $str;
        }
        return $str_arr['path'] ?? $str;
    }
}

/**
 * 添加域名
 * @param string $url url地址
 * @param string $domain 域名
 *
 * @return string
 * */
if(!function_exists('addDomain')){
    function addDomain(string $url,string $domain = ''):string
    {
        $domain = $domain ?: Request::domain();
        return !$url ? $url : (strstr($url, 'http') !== false ? $url : $domain . trim($url,'.'));
    }
}

/**
 * 对象方式获取日期时间或时间戳(U)毫秒(v)
 *
 * @param string|array $format 日期时间格式,时间戳(U)毫秒(v)
 * @param string|int $datetime 初始时间
 * @param string $zone 时区
 * @return bool|string|array
 *
 * */
if(!function_exists('getDateTime')){
    function getDateTime($format = '', $datetime = '', string $zone = '')
    {
        try {
            $timeZone = $zone ? new DateTimeZone($zone) : null;
            $datetime = $datetime ?: 'now';
            $isTimestamp = is_numeric($datetime) && strlen($datetime)===10;
            if($isTimestamp){
                $d = new DateTime('now', $timeZone);
                $d->setTimestamp($datetime);
            }else{
                $d = new DateTime($datetime, $timeZone);
            }
            if(is_array($format)){
                if(count($format)){
                    $result = [];
                    foreach ($format as $k=>$f){
                        $result[$k] = $d->format($f);
                    }
                }else{
                    $format = $format ?: 'Y-m-d H:i:s';
                    $result = $d->format($format);
                }
            }else{
                $format = $format ?: 'Y-m-d H:i:s';
                $result = $d->format($format);
            }

            return is_numeric($result) ? intval($result) : $result;
        } catch (\Exception $e) {
            return false;
        }
    }
}

/**
 * 自定义缓存处理
 * @param string $key 键名
 * @param string $type 处理类型：pull,push,set,get,delete
 * @param string|array|null $value
 * @param int $expire 过期时间
 * */
if(!function_exists('cacheDo')){
    function cacheDo($key,$type='get',$value='',$expire=0){
        $type = strtoupper($type);
        $result = '';
        switch($type){
            case 'PULL':
                $result = Cache::pull($key);//获取并删除
                Cache::set($key,[]);
                break;
            case 'PUSH':
                Cache::push($key,$value);//追加
                $result = true;
                break;
            case 'DELETE':
                Cache::delete($key);//删除
                $result = true;
                break;
            case 'SET':
                Cache::set($key,$value,$expire);//设置
                $result = true;
                break;
            default:

        }

        return $result;
    }
}

/**
 * @param $longitude 经度
 * @param $latitude 维度
 * @param $raidus 半径（米）
 * @return float[]
 */
if(!function_exists('getAround'))
{
    function getAround($longitude, $latitude, $raidus)
    {
        $degree = (24901 * 1609) / 360.0;
        $dpmLat = 1 / $degree;
        $radiusLat = $dpmLat * $raidus;
        $minLat = $latitude - $radiusLat;
        $maxLat = $latitude + $radiusLat;
        $mpdLng = $degree * cos($latitude * (pi() / 180));
        $dpmLng = 1 / $mpdLng;
        $radiusLng = $dpmLng * $raidus;
        $minLng = $longitude - $radiusLng;
        $maxLng = $longitude + $radiusLng;
        return array('minLng' => $minLng, 'maxLng' => $maxLng, 'minLat' => $minLat, 'maxLat' => $maxLat);
    }
}

/**
 * 获取数组第一个键名
 * @param array $array 数组
 * @return string|null|int
 */
if(!function_exists('array_key_first'))
{
    function array_key_first($array)
    {
        $key = null;
        if(!empty($array)){
           foreach ($array as $k=>$a){
               $key =  $k;
               break;
           }
        }
        return  $key;
    }
}

